package com.zego.wawaji.ui.play;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.zego.wawaji.R;
import com.zego.wawaji.base.log.PLogger;
import com.zego.wawaji.base.observer.MsgMgr;
import com.zego.wawaji.base.observer.MsgType;
import com.zego.wawaji.base.utils.JsonUtil;
import com.zego.wawaji.third.zego.ZegoMgr;
import com.zego.wawaji.third.zego.im.callback.ZegoIMCallack;
import com.zego.wawaji.third.zego.im.callback.ZegoRoomCallback;
import com.zego.wawaji.third.zego.im.listener.ZegoListener;
import com.zego.wawaji.ui.base.BaseAppCompatActivity;
import com.zego.wawaji.ui.bean.wawa.WawaJi;
import com.zego.wawaji.wawaji_client.cmd.CommandUtil;
import com.zego.wawaji.wawaji_client.play.BoardState;
import com.zego.wawaji.wawaji_client.play.PlayStatus;
import com.zego.zegoliveroom.ZegoLiveRoom;
import com.zego.zegoliveroom.callback.IZegoLoginCompletionCallback;
import com.zego.zegoliveroom.constants.ZegoConstants;
import com.zego.zegoliveroom.entity.ZegoStreamInfo;
import com.zego.zegoliveroom.entity.ZegoUser;

import java.util.ArrayList;
import java.util.Map;

/**
 * 娃娃机游戏页
 */
public class PlayActivity extends BaseAppCompatActivity implements ZegoListener {
    private WawaJi mRoom;
    private ZegoLiveRoom mZegoLiveRoom;

    private PlayHead head;
    private PlayHandle handle;
    private PlayFoot foot;

    private boolean isInput = false;      // 输入框是否正在展示
    private PlayInputPanel inputPanel;      // 输入框
    private LinearLayout msgContainer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        isCanBack(false);
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        if (intent != null) {
            mRoom = intent.getParcelableExtra("room");
        } else {
            Toast.makeText(this, "房间信息初始化错误, 请重新开始", Toast.LENGTH_LONG).show();
            finish();
        }
        setContentView(R.layout.activity_play);
        mZegoLiveRoom = ZegoMgr.getInstance().getZegoLiveRoom();

        initView();
        startPlay();
    }

    private void initView() {
        // ModuleMgr.getWawaMgr().reqRoomjoin(mRoom.getId(), null);  // 加入游戏房间，通知服务器
        mRetryHandler = new RetryHandler(Looper.getMainLooper());

        LinearLayout headContainer = (LinearLayout) findViewById(R.id.head_container);
        LinearLayout handleContainer = (LinearLayout) findViewById(R.id.container);

        inputPanel();
        head = new PlayHead(this, mRoom, mZegoLiveRoom);
        headContainer.addView(head.getContentView());
        handle = new PlayHandle(this, mRoom, mZegoLiveRoom);
        handleContainer.addView(handle.getContentView());
        foot = new PlayFoot(this, mRoom);
        handleContainer.addView(foot.getContentView());
    }

    private void inputPanel() {
        msgContainer = (LinearLayout) findViewById(R.id.play_msg_container);
        inputPanel = new PlayInputPanel(this);
        msgContainer.addView(inputPanel.getContentView());

        findViewById(R.id.play_mask).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isInput) {
                    msgContainer.setVisibility(View.INVISIBLE);
                    inputPanel.refresh(View.GONE);
                    isInput = false;
                }
                return false;
            }
        });

        inputPanel.setInputPanelListener(new PlayInputPanel.InputPanelListener() {
            @Override
            public void onInputbtnClick(View v) {
                if (isInput) {
                    msgContainer.setVisibility(View.INVISIBLE);
                    inputPanel.refresh(View.GONE);
                    isInput = false;
                }
            }
        });
    }

    public void showInputPanel() {
        if (!isInput) {
            msgContainer.setVisibility(View.VISIBLE);
            inputPanel.refresh(View.VISIBLE);
            isInput = true;
        }
    }

    private void startPlay() {
        if (loginRoom()) { // 登录房间成功
            setupCallbacks();  // 登录房间成功后设置回调
            head.netStatus();
            head.setupCallbacks(this);
        }
    }

    private Handler mRetryHandler;
    private ZegoStreamInfo streamInfo;
    private int audienceNum;            // 观众人数

    /**
     * 登录房间操作： 不成功重试登录
     */
    private boolean loginRoom() {
        return mZegoLiveRoom.loginRoom(mRoom.getRoomId(), ZegoConstants.RoomRole.Audience, new IZegoLoginCompletionCallback() {
            @Override
            public void onLoginCompletion(int errCode, ZegoStreamInfo[] zegoStreamInfos) {
                if (errCode == 0) {
                    mRetryHandler.removeMessages(RetryHandler.MSG_RELOGIN_ROOM);
                    for (ZegoStreamInfo stream : zegoStreamInfos) {
                        // {"player":{"id":"","name":""},"queue_number":0,"total":1}
                        if (!TextUtils.isEmpty(stream.extraInfo)) {
                            streamInfo = stream;

                            Map<String, Object> map = JsonUtil.getMapFromJson(stream.extraInfo);
                            if (map != null) {
                                int count = ((Double) map.get("queue_number")).intValue();
                                handle.refreshQueueNum(count);
                                handle.parseQueueNum((ArrayList) map.get("queue"));

                                audienceNum = ((Double) map.get("total")).intValue();
                                head.refreshUserCount(audienceNum);

                                if (imCallack != null) {
                                    imCallack.setAudienceNum(audienceNum);
                                }
                            }
                        }
                    }
                    setAnchor();
                } else {    // 失败后重新登录
                    mRetryHandler.sendEmptyMessageDelayed(RetryHandler.MSG_RELOGIN_ROOM, 100);
                }
            }
        });
    }

    private void setAnchor() {
        ZegoUser zegoUser = new ZegoUser();

        // 180106113506597, WWJS_rk7130s_180106113506597
        if (streamInfo == null) {
            zegoUser.userID = "";
            zegoUser.userName = "";
        } else {
            zegoUser.userID = TextUtils.isEmpty(streamInfo.userID) ? "" : streamInfo.userID;
            zegoUser.userName = TextUtils.isEmpty(streamInfo.userName) ? "" : streamInfo.userName;
        }
        CommandUtil.getInstance().setAnchor(zegoUser);
        MsgMgr.getInstance().sendMsg(MsgType.MT_Init_Suc, true);
    }

    /**
     * 登录房间失败或推流失败后，重新登录
     */
    private class RetryHandler extends Handler {
        static final int MSG_RELOGIN_ROOM = 1;

        public RetryHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_RELOGIN_ROOM:
                    loginRoom();
                    break;

                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }

    /**
     * 处理来自服务器的消息.
     */
    private void handleRecvCustomCMD(String msg) {
        PLogger.d("receiverCMDformSSersfk=====: " + msg);

        Map<String, Object> map = JsonUtil.getMapFromJson(msg);
        if (map == null) return;

        int cmd = ((Double) map.get("cmd")).intValue();
        int rspSeq = ((Double) map.get("seq")).intValue();
        Map<String, Object> data = (Map<String, Object>) map.get("data");

        if (data != null) {
            // 解析预约队列用户列表
            handle.parseQueueNum((ArrayList) data.get("queue"));
        }
        switch (cmd) {
            case CommandUtil.CMD_APPLY_RESULT:    // 预约结果
                handle.handleApplyResult(data);
                break;
            case CommandUtil.CMD_CANCEL_APPOINTMENT_REPLY: // 取消预约
                break;
            case CommandUtil.CMD_GAME_READY:
                PlayHelper.handleGameReady(this, rspSeq, data);
                break;
            case CommandUtil.CMD_CONFIRM_BOARD_REPLY:
                handle.handleConfirmBoardReply(data);
                break;
            case CommandUtil.CMD_GAME_RESULT:
                handle.stopWaitGameResultTimer();
                PlayHelper.handleGameResult(this, rspSeq, data);
                break;
            case CommandUtil.CMD_USER_UPDATE:
                break;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            logout(this);   // 退出检测是否在游戏中
        }
        return super.onKeyDown(keyCode, event);
    }

    public void logout(Context context) {
        if (PlayStatus.getCurrentBoardSate() != BoardState.Ended) {
            AlertDialog dialog = new AlertDialog.Builder(context).setMessage("正在游戏中，确定要离开吗？").setTitle("提示").setPositiveButton("离开", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    finish();
                }
            }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            }).create();
            dialog.show();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        PlayHelper.playSound();
        handle.refreshCoin();
    }

    @Override
    protected void onPause() {
        super.onPause();
        PlayHelper.stopPlay();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    public void finish() {
        super.finish();
        doLogout();
    }

    private void doLogout() {
        if (head != null)
            head.doLogout();
        handle.doLogout();
        foot.doLogout();
        mZegoLiveRoom.logoutRoom();
        if (imCallack != null) {
            imCallack.release();
            imCallack = null;
        }

        PlayHelper.reset();
        CommandUtil.getInstance().reset();
        PlayStatus.resetStatus();
        mRetryHandler.removeCallbacksAndMessages(null);
        MsgMgr.getInstance().sendMsg(MsgType.MT_Update_MyInfo, null);
    }

    // =======================================  接口回调 ====================================
    private ZegoIMCallack imCallack = new ZegoIMCallack(this);

    /**
     * 设置各种回调监听
     */
    private void setupCallbacks() {
        mZegoLiveRoom.setZegoIMCallback(imCallack);
        mZegoLiveRoom.setZegoRoomCallback(new ZegoRoomCallback(this));
    }

    @Override
    public void roomTotalNum(int num) {
        head.refreshUserCount(num);
    }

    @Override
    public void onRecvCustomCommand(String fromUserId, String fromUserName, String content, String roomId) {
        // 只接收当前房间，当前主播发来的消息
        if (CommandUtil.getInstance().isCommandFromAnchor(fromUserId) && mRoom.getRoomId().equals(roomId)) {
            if (!TextUtils.isEmpty(content)) {
                handleRecvCustomCMD(content);
            }
        }
    }

    @Override
    public void onPlayStateUpdate(int errCode, String streamID) {
        head.refreshPlayStateUpdate(errCode, streamID);
    }

    @Override
    public void onVideoSizeChangedTo(String streamID, int i, int i1) {
        head.refreshVideoSizeChangedTo(streamID, i, i1);
    }
}
